JSConf.jp おかわり Node学園46時限目
https://www.youtube.com/watch?v=q5ZkrvP46RQ
JSConf.jp おかわり Node学園46時限目 - connpass
PEPCはパーミッションモデルをどのように変えるのか
PEPCは何を変えようとしていたのか - Speaker Deck
ken7253
PEPC
Page Embedded Permisson Control
<permisson>要素
現在のブラウザにおける権限管理
try catchでエラーハンドリング
それは使いやすいのか?
問題点
どの要素がどの権限のリクエストがセマンティックに表現されていない
権限のリクエスト要素とプロンプト位置の乖離
"permanent deny" policy
リクエストを何度も遅れないようにする背景
課題
AppleとMozillaはネガティブ
仕様が複雑
クリックジャギングが可能になる
課題を2つに分けて代替え案を検討
プロンプトを改善する
権限の許可フローを改善
Cloudflare Workers in Production
https://jsconf2024-slide.buddha0818.workers.dev/
Motoki Shakagori
サービス概要
Spir for Agent
アーキテクチャ
https://gyazo.com/6c5f2128cd0ecc6ffae06748c13ad1d7
Cloudflare Workersの採用理由
コンテナはデプロイが重い
既存はNode.js on Cloud Run
Remixがデプロイしやすい
開発体験がよいので使ってみたい気持ちがある
検証段階をすぎても脱出は容易と判断
Cloudflare Workersのランタイム
Node.js向けのライブラリが動く保証はない
とはいえそれで困ったことはいまだにない
Webフレームワークを除けば、意外にNode.js向けのライブラリは使わない(ブラウザでも動くやつを使う)
ローカル開発環境
Wrangler
dev server立ち上げからdeployまで担う
dev serverは本番と同等のランタイムで動く
tsも事前のコンパイルなしで実行可能(型検査は別途実行する必要あり)
Cloudflare KV, R2などのCloudflareサービスのエミュレータ付き
Remixの開発ではVite pluginを通してWorkersのランタイムを使う
テスト
Cloudflare公式の@cloudflare/vitest-pool-workersというVitestプラグインを使う
フロントエンド
Remix
責務
サーバーサイドでコードを実行できるので、DB呼び出しを含むビジネスロジックも全てRemixの中に書くことも可能
今回の開発では、APIからデータを取得して整形するだけのBFF的な役目に徹する
Webアプリ以外のクライアントが生えたときのことを考えるとバックエンドを分離しておいた方が綺麗
非同期処理のバッチなど
Workers間の通信が非常に高速で分離するコストが低い
通信について
Service Binding
ネットワークのオーバーヘッドなし
code:json
// service-aというWorkerからservice-bというWorkerを呼び出す場合
{
"name": "service-a",
"services": [
{
"binding": "SERVICE_B", // コードから呼びだすときの名前
"service": "service-b", // デプロイするときにつけた名前
},
],
}
インターフェースはfetchなのでHTTP越しのやりとりにしか見えない
移植性が高くなっている
別のクラウドにうつってもコードの見た目が変えずに移行が可能
パブリックアクセスを無効にできる
ローカルでもエミュレートできる
code:index.ts
export default {
async fetch(request, env) {
return await env.SERVICE_B.fetch(request);
},
};
バックエンド
Hono
もともとはCloudflare Workersで動かすために作られたもの
Hono RPC
クライアント側にリクエストとレスポンスのTypeScript型を共有できる
code:server.ts
import { Hono } from "hono";
const app = new Hono()
.get("/hello", (c) => c.json({ message: "Hello, World!" }))
.get("/dog", (c) => c.json({ face: "🐶" }));
export type AppType = typeof app;
export default app;
code:client.ts
import { hc } from "hono/client";
import type { AppType } from "./server";
const client = hc<AppType>("http://localhost:8787");
await client.hello.$get().then((res) => res.json()); // { message: string }型
await client.dog.$get().then((res) => res.json()); // { face: string } 型
Sentry
@sentry/cloudflareがあるので動く
エラーとトレースのみ
現時点ではプロファイルは取れない
分散トレースもバッチリ
撤退戦略
失敗したらどうするの?という問いに答えをもっておきたい
インフラ載せ替えは難しくないと判断
RemixとHonoはそもそもランタイム非依存
アダプタを切り替えるだけ
Service Bindingはprivate networkに置き換え
fetchインターフェースなのでコードの変更は少ない
KVなどの他のCloudflareのサービスを使っている場合のみ、置き換え先を探す必要あり
「The Clean Architecture」がWebフロントエンドでしっくりこないのは何故か - 制約から考えるアーキテクチャとテスト
t_wada
現状認識
DDDやクリーンアーキテクチャってしっくりこない話
JSフレームワークは制約があるので当てはまらない
しっくりこない=悪くないけど良くもない、モヤモヤ
ソフトウェアアーキテクチャは何のためにあるのかを学ぶとモヤモヤが晴れる
https://speakerdeck.com/koichik/isomorphic-survival-guide?slide=12
サーバーが一分かかっている
ソフトウェアアーキテクチャとは何か
The Clean Architecture
保守性に全振りしたソフトウェアの形状をもとめる形?
Design It!
望まれる品質特性を促進するためにどう構築するか
SQuaRE
Webフロントエンドの品質特性って?
Webフロントエンド版DX Criteria (v202402)/プロダクトのユーザー体験と変化に適応するチームのためのガイドライン
パフォーマンス
アクセシビリティ
セキュリティ
プライバシー
デザイン
アーキテクチャドライバ
制約
変えられない設計判断のこと
デバイスやブラウザの制約
ネットワークの制約
セキュリティの制約
SEOの制約
Core Web Vitals
バックエンドとの違い
https://gyazo.com/599e45472bc4cdf50832f71edf4a72cf
UI
実行環境の多様性
状態管理
ビジネスロジック
パフォーマンス
信頼性
セキュリティの界面
JavaScriptフレームワークはクラスと相性が悪い話
OOPはGUIに向いているのでは?
むしろバックエンドより生きるのでは?なぜ避けているのか?
品質特性と制約にヒントがあるのではないか
1. 変更検知
ユーザービリティのために再レンダリングさせたい
インスタンス比較より値の比較のが早いし簡単
2. バンドルサイズ
モジュールフェデレーション化にはクラスとESM
Tree Shakingに向いているのはクラスではなくESM
OOPは決定は遅ければ遅いほどでいい世界線
だからポリモーフィズムで動く
でも決定が遅れると使っているかどうかがわからない、ブラウザへ持っていくほかない
隠されているものがないと削れるものが増える
純粋関数が優れている理由になる
静的解析
スタイル変更の背後にはトレードオフの解決
Rustは安全性とパフォーマンスの両立のために納得させた
Playwrightでブラウザを拡張する
yebis0942
日常のブラウザ操作も自動化ができるがそれ以外もできるのではないか?
ベースマキナのビュー機能
playwrightで試す
ローカルファイルを監視
ファイルが更新されたらページ内のエディタに投入する
監視する
playwrightは人が使うためのChromiumではなかった
viewportは常に固定
1280x720
ダイアログで自動で閉じる
window.alert, window.confirmは自動的に閉じる
monacoへどうやってplaywrightから入力するのか?
locatorでDOM要素をつかんでClickしてからpressSequentiallyでキー入力を流し込む
WebページからNode.jsにシグナルを送るには?
addEventListnerする
プロセスが分離しているからできない
案1
DOM要素を監視する
DOM要素をイベントベースで監視できない
expectはポーリングで実装されている
案2
Page.exposeFunction
Webページに関数を登録できる
実態はRPC
案3
API Testing機能
ダミーHTTPサーバーを差し込める
双方向通信ができそう
Webフレームワークとともに利用するWeb Components
Webフレームワークとともに利用するWeb components / JSConf.jp おかわり - Speaker Deck
spring_raining
Web Componentsのつらみ
Web APIだけで実装するのが大変?
既存のフレームワークのCustom Elementsビルド機能
Custom Elementsとしてビルドするフレームワーク
ケースにはよるけど基本こちらに寄せたい
バンドルサイズで不利
フレームワークの将来的に見てサポートするとは限らない
LitのAPI設計
プリミティブな部分まで分割している
LitElement
ReactiveElement
状態管理はZag.jsに移譲する
フレームワークと組み合わせて使えない?
Custom Elements Everywhere
React 19より対応
問題は解決した?
TypeScriptの型でCustom ElementsのPropsは表現できない
Custom-elements-manifest
https://github.com/webcomponents/custom-elements-manifest
構成やメタデータを宣言的にJSONに表現する
propsの抽出
defineComponentPropsメソッド
型パラメータとしてpropsの情報を記述
cemの抽出をするだけ
cemを元にラッパーコンポーネントを生成する
SSR、RSCには対応していない?
Declarative ShadowDOMで対応できる
Shadow boundaryの問題
フロントエンドで日時処理と戦うために 2024 2025ver
sajikix
タイムゾーン
増減がある、時差が変更になる、名称が変わる
2023年は4回変わった
サマータイム
春頃:夜中の1時間がなくなる
秋頃:夜中の時刻が2回くる
カレンダー歴
グレゴリオ暦
旧暦、ユダヤ歴、イスラム暦
1年が同じ月あるわけでもない
日時に関する仕様・リソース
RFC 9110(RFC 5322)
HTTPでも継承
ISO 8601とRFC 3339
JSの標準フォーマット
Data.prototype.toUTCString()で生成
IANA TZ database
BCP 175に定められている
iCalendar RFC 5545
IETF言語タグ(BCP47)
Ja-JP
RFC 5646, RFC 4647
LDML(UTS#35)
XMLによるフォーマット
各ロケールデータをもっているのがCLDR
JSのDateと課題
システムとUTCのタイムゾーンしかサポートしていない
グレゴリオ暦しか使えない
日時文字列のパース挙動が分かりにくい
Set系のメソッドが破壊変更
計算系のユーティリティメソッドがない
ライブラリによる一定の解決
Intlで書式の問題を解決
formatToParts()
Temporalへの期待
今後は何を意識すべきか
日時はなにを意識するのか
タイムゾーン、カレンダー、書式化のせいでめんどくさくなっている
タイムゾーン:変換層をちゃんとつくる
カレンダー:ローカルな日時側を意識する
書式:Intl.DataTimeFormatで解決できそう